package high.concurent.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import high.concurent.dao.UserMapper;
import high.concurent.feign.CouponFeignService;
import high.concurent.model.UserDO;
import high.concurent.request.UserLoginRequest;
import high.concurent.request.UserRegistryRequest;
import high.concurent.service.NotifyService;
import high.concurent.service.UserService;
import high.concurent.vo.UserVO;
import high.concurrent.dto.NewUserDTO;
import high.concurrent.enums.BizCodeEnum;
import high.concurrent.interceptor.UserInterceptor;
import high.concurrent.model.LoginUser;
import high.concurrent.utils.CommonUtil;
import high.concurrent.utils.JWTTokenUtil;
import high.concurrent.utils.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService {


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private NotifyService notifyService;

    @Autowired(required = false)
    private UserMapper userMapper;

    @Autowired
    private CouponFeignService couponFeignService;

    @Override
    public String uploadUserImg(MultipartFile file) {
        return null;
    }

    /**
     * 用户注册
     * * 验证码校验(邮箱/手机)
     * * 密码加密
     * * 找好唯一性校验
     * * 插入数据库
     * * 从redis删除验证码
     * * 注册新用户福利发放
     * @param userRegistryRequest
     * @return
     */
    @Override
//    @GlobalTransactional
//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public JsonData registry(UserRegistryRequest userRegistryRequest) {

//        // 验证码校验结果
//        boolean checkResult = false;
//
//        //校验验证码
//        if(userRegistryRequest.getCaptchaCodeType() == 1){
//            // 邮箱验证
//            checkResult = notifyService.checkCaptchaCode(userRegistryRequest.getCaptchaCode(), userRegistryRequest.getMail());
//        }else{
//            // TODO 手机验证
//            //checkResult = notifyService.checkCaptchaCode(userRegistryRequest.getCaptchaCode(), userRegistryRequest.getPhone());
//        }
//
//        // 验证码校验失败则直接返回
//        if(!checkResult){
//            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
//        }

        // 信息注入到DO
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userRegistryRequest, userDO);
        userDO.setCreateTime(new Date());
        userDO.setPwd(CommonUtil.MD5(userRegistryRequest.getPwd()));

        // 唯一性校验(检测存在，所以如果checkExistUnique返回false，则账号不存在)
        if(!checkExistUnique(userRegistryRequest.getMail())){

            // 账号唯一
            int result = userMapper.insert(userDO);
            log.info("用户注册成功: rows:{}, 信息:{}", result, userDO.toString());

            // TODO 异步发放福利(暂时先不用MQ, 用seata)
            this.RPCNewCouponRecord(userDO);

            return JsonData.buildSuccess();
        }else{

            log.info("账号已存在");
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_REPEAT);
        }

    }


    /**
     * 注册给新人发放优惠券
     * @param userDO
     */
    private void RPCNewCouponRecord(UserDO userDO) {

//        // 赋值DTO所需的参数值
//        NewUserDTO newUserDTO = new NewUserDTO();
//        newUserDTO.setName(userDO.getName());
//        newUserDTO.setUserId(userDO.getId());
//        JsonData jsonData = couponFeignService.RPCNewCouponRecord(newUserDTO);
//        log.info("优惠券发放成功：{}, 参数: {}", jsonData.toString(), newUserDTO);
//
//        if(jsonData.getCode() != 0){
//            throw new RuntimeException("下游服务异常");
//        }
    }


    /**
     * 用户登录
     * @param userLoginRequest
     * @return
     */
    @Override
    public JsonData login(UserLoginRequest userLoginRequest) {

        // 查询该邮箱是否存在与数据库
        List<UserDO> listUserDOs = userMapper.selectList(new QueryWrapper<UserDO>().eq("mail", userLoginRequest.getMail()));
        if(listUserDOs != null && listUserDOs.size() == 1){

            // 符合登录条件, 校验密码正确性(需要对明文MD5加密)
            if(listUserDOs.get(0).getPwd().equals(CommonUtil.MD5(userLoginRequest.getPwd()))){

                // 生成token，并返回
                LoginUser loginUser = LoginUser.builder().build();
                BeanUtils.copyProperties(listUserDOs.get(0), loginUser);
                String token = JWTTokenUtil.geneJsonnWebToken(loginUser);
                return JsonData.buildSuccess(token);
            }
        }

        // 账号不存在，用户名或者密码错误，统一报用户名或密码错误，迷惑黑客
        log.info("账号或密码错误");
        return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
    }

    /**
     * 查询用户详情
     * @return
     */
    @Override
    public JsonData getUserDetail() {

        // 从threadLocal中获取解析token获取的用户信息
        LoginUser loginUser = UserInterceptor.threadLocal.get();
        if(loginUser == null){

            // 用户信息为空，说明token没解析出来用户信息，直接返回用户未登录
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_UNLOGIN);
        }

        // 根据用户id，查询用户具体信息，并转换成VO返给前端
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().eq("id", loginUser.getId()));
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userDO, userVO);

        return JsonData.buildSuccess(userVO);
    }

    /**
     * 账号唯一性校验
     * @param mail  邮箱
     * @return
     */
    private boolean checkExistUnique(String mail) {

        // 通过邮箱去数据库检查用户是否存在
        List<UserDO> userDOs = userMapper.selectList(new QueryWrapper<UserDO>().eq("mail", mail));

        return userDOs != null || userDOs.size() > 0 ? false:true;
    }
}
